import threading
import socket
import select


class SocketServer:
    def __init__(self):
        self._stop = False
        self.port = 6310
        self.socket = None
        self.client = []

        self.thread = threading.Thread(target=self.start,
                                       name='socket_server')
        self.thread.start()

    def initSocket(self):
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        s.bind(('', self.port))
        s.listen(1)

        self.socket = s

    def start(self):
        self.initSocket()
        print('waiting for clients to connect.')
        while not self._stop:
            # 1 秒种超时一次, 及时响应 Ctrl-C 退出指令
            r, w, e = select.select([self.socket], [], [], 1)
            if not r:
                continue
            client, addr = self.socket.accept()
            self.client.append({'client': client, 'addr': addr})
            print('A connect from: %s:%d' % addr)

    def stop(self):
        self._stop = True
        self.socket.close()
        self.thread.join()
        for item in self.client:
            item['client'].close()

    def send(self, buf):
        if not self.client:
            try:
                print(buf.decode(), end="")
            except UnicodeDecodeError:
                pass

        for item in self.client:
            try:
                item['client'].send(buf)
            except BrokenPipeError:
                print('close connect to: %s:%d' % item['client'].addr)
                item['client'].close()
                self.client.remove(item)
